home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 08 - 1992 / 08.01 Apr⁄May 92 / ~3D Graphics Tools / Lamp.c
Encoding:
C/C++ Source or Header  |  1991-12-17  |  10.2 KB  |  418 lines  |  [TEXT/KAHL]

  1. /*
  2.     Program:    Lamp.c
  3.     
  4.     Purpose:    Tutorial demonstration -- Lamp on Table
  5.     
  6.     ©1991 Mark M. Owen -- All Rights Reserved.
  7.  */
  8.  
  9. /*    Compiler specific headers
  10.  */
  11. #pragma    segment    Main
  12.  
  13. #ifndef THINK_C
  14.  
  15. #include <OSEvents.h>
  16. #include <Fonts.h>
  17. #include <Desk.h>
  18. #include <Dialogs.h>
  19. #include <Menus.h>
  20. #include <Memory.h>
  21. #include <Packages.h>
  22. #include <Quickdraw.h>
  23. #include <Resources.h>
  24. #include <Traps.h>
  25. #include <Windows.h>
  26.  
  27. extern _DataInit();
  28.  
  29. #endif    THINK_C
  30.  
  31. /*    3d Graphic Tools headers (for things we'll use only)
  32.  */
  33. #include <3dExterns.h>
  34. #include <3dGrid.h>
  35. #include <3dHermiteCurves.h>
  36. #include <3dHierarchy.h>
  37. #include <3dResources.h>
  38. #include <3dMatrix2Patch.h>
  39. #include <3dQuadratics.h>
  40. #include <3dSolidsPgn.h>
  41. #include <3dSpline2Patch.h>
  42. #include <3dText.h>
  43. #include <Camera.h>
  44. #include <OffScreenPorts.h>
  45. #include <SysEnvirons.h>
  46.  
  47.  
  48. /*    define this to observe the offscreen drawing effects
  49.  */
  50. #undef    _OFFSCREEN_
  51.  
  52.  
  53. /*    Define resource related items
  54.  */
  55. #define    RESOURCEFILE    "\pLamp.π.rsrc"
  56. #define    WINDOWID        1001
  57.  
  58. /*    Define a few, miscellaneous, fixed point constants
  59.  */
  60. #define    f_0p1    6554L
  61. #define    f_0p4    26214L
  62. #define    f_0p6    39322L
  63. #define    f_3p6    235930L
  64. #define f_6        393216L
  65.  
  66. /*    Prototypes for our functions... very important
  67.  */
  68. void        main                    (void);
  69. void        ProduceScene            (void);
  70. void        DrawGrid                (void);
  71. hCollection    MakeLamp                (void);
  72. void        GenRotatedSurfaceBody    (hGroup hG,short ixP);
  73. void        GenRotatedSurfaceTable    (hGroup hG,short ixP);
  74. void        SetRenderingAttributes    (pRendAttr pRA,colorFactor r,colorFactor g,colorFactor b);
  75. pLighting    SetupLighting            (void);
  76.  
  77.  
  78. void main()
  79. {
  80.     short    masters = 4;
  81.     EventRecord    evt;                /* for event polling            */
  82.     WindowPtr    wp;
  83.     
  84. #ifndef THINK_C
  85.     UnloadSeg(_DataInit);    /* for MPW C only, get rid of Data Initializer after use */
  86. #endif
  87.  
  88.     MaxApplZone();
  89.     while( masters-- )
  90.         MoreMasters();
  91.     FlushEvents(everyEvent, 0);
  92. #ifndef    THINK_C
  93.     InitGraf(& QDGLOBALS thePort);
  94. #else
  95.     InitGraf(&thePort);
  96. #endif    THINK_C
  97.     InitFonts();
  98.     InitWindows();
  99.     InitMenus();
  100.     TEInit();
  101.     InitDialogs(0L);
  102.  
  103.     OpenResFile( RESOURCEFILE );
  104.     SelectWindow( (wp = GetNewCWindow( WINDOWID, (Ptr)0L, (WindowPtr)-1L )) );
  105.     SetPort( wp );
  106.     
  107.     Init3d();
  108.  
  109.     ProduceScene();
  110.  
  111.     while( !GetNextEvent( mDownMask|keyDownMask, &evt ) );
  112.     
  113.     FlushEvents(everyEvent, 0);        /* get rid of any leftovers        */
  114.     DisposeWindow( FrontWindow() );    /* don't need this anymore        */
  115.     ExitToShell();                    /* we are out of here... NOW!    */
  116. }
  117.  
  118. void    ProduceScene()
  119. {
  120.     hCollection hC;                            /*    collection storage reference    */
  121.     Point3d        Camera    = {-f_100,f_45,-f_180};/*    camera location                */
  122.     Point3d        Focus    = {f_0,f_0,f_0};    /*    camera focus point                */
  123.     Fixed        Lens    = Lens80mm;            /*    angle of view / magnification    */
  124.     pLighting    pL;                            /* lighting information             */
  125.     WindowPtr    theWindow = FrontWindow();
  126.     GrafPtr        osGP;
  127.  
  128.     /*    Generate the scene objects
  129.      */
  130.     hC = MakeLamp();
  131.     
  132.     AimCamera3d( Camera.x,Camera.y,Camera.z, Focus.x,Focus.y,Focus.z, Lens );
  133.     
  134.     /*    Setup ambient and point light sources
  135.      */
  136.     pL = SetupLighting();
  137.  
  138. #ifdef    _OFFSCREEN_
  139.     /*    Create offscreen drawing port
  140.      */
  141.     if( ColorPresent )
  142.     {
  143.         osGP = (GrafPtr)NewOffScreenCPort( &theWindow->portRect );
  144.         UseOffScreenCPort( (CGrafPtr)osGP );
  145.     }
  146.     else
  147.     {
  148.         osGP = NewOffScreenPort( &theWindow->portRect );
  149.         UseOffScreenPort( osGP );
  150.     }
  151. #endif    _OFFSCREEN_    
  152.     
  153.     /*    Clear the screen
  154.      */
  155.     EraseRect( &theWindow->portRect );
  156.     
  157.     DrawGrid();
  158.     
  159.     /*    Decide how to render it based on the graphics device bit depth
  160.      */
  161.     if( GDevicePixelBits() > 8 )
  162.     {    /*    We have a VERY good screen so use ZBuffered rendering method
  163.          */
  164.         SetAntiAliasing(true);
  165.         xfRenderCollectionPgn( hC, &xFormViewer, pL );
  166.     }
  167.     else
  168.         /*    We have only a basic mono, grayscale or 8 bit color screen
  169.          *    so use the Paint rendering method
  170.          */
  171.         xfRenderCollection( hC, &xFormViewer, pL, false );
  172.     
  173.     /*    release some of the memory we allocated
  174.      */
  175.     DisposeCollection( hC );
  176.     DisposPtr( (Ptr)pL );
  177.  
  178. #ifdef    _OFFSCREEN_
  179.     /*    Display the offscreen buffer and dispose of it
  180.      */
  181.     if( ColorPresent )
  182.     {
  183.         ShowOffScreenCPort( (CGrafPtr)osGP, theWindow );
  184.         DisposeOffScreenCPort( (CGrafPtr)osGP );
  185.     }
  186.     else
  187.     {
  188.         ShowOffScreenPort( osGP, theWindow );
  189.         DisposeOffScreenPort( osGP );
  190.     }
  191. #endif    _OFFSCREEN_
  192. }
  193.  
  194. void    DrawGrid(void)
  195. {
  196.     Point3d        min        = { -f_16,-f_16,-f_16 };
  197.     Point3d        max        = {  f_16, f_16, f_16 };
  198.     Point3d        steps    = { f_8,f_8,f_8 };
  199.     GridOptions    options;
  200.     
  201.     options.left    = false;
  202.     options.right    = true;
  203.     options.top        = false;
  204.     options.bottom    = true;
  205.     options.front    = false;
  206.     options.back    = true;
  207.     options.gridPat    = GP_BLACK;
  208.     options.connectX= false;
  209.     options.connectY= false;
  210.     options.connectZ= false;
  211.     ForeColor( blueColor );
  212.     xfGrid( min, max, steps, options, &xFormViewer );
  213.     ForeColor( blackColor );
  214.     xFormCombined = xFormViewer;
  215.     TextFace( bold );
  216.     TextFont( geneva );
  217.     TextSize( 12 );
  218.     DrawString3d(min.x,f_0,max.z,"\pX",centerAlign);
  219.     DrawString3d(f_0,max.y,max.z,"\pY",centerAlign);
  220.     DrawString3d(f_0,min.y,min.z,"\pZ",centerAlign);
  221. }
  222.  
  223. hCollection    MakeLamp()
  224. {
  225.     hCollection hC;            /*    collection storage reference    */
  226.     hGroup        hG;            /*    group storage reference            */
  227.     RendAttr    RA;            /* working copy of rendering attributes    */
  228.  
  229.     hC = NewCollection( 2 );/* allocate storage for collection    */
  230.     hG = NewGroup( 4 );        /* ditto for the group and patches    */
  231.     
  232.     (**hC).hG[0] = hG;        /* put group handle in collection    */
  233.     
  234.     /*    Make the lamp body
  235.      */
  236.     GenRotatedSurfaceBody( hG, 0 );
  237.  
  238.     /*    Now a cylinder for the bulb support
  239.      */
  240.     SetRenderingAttributes( &RA, 32767,32767,32767 );
  241.     SetInstanceReferenceFrame(f_0,f_0,f_0,f_1,f_1,f_1,f_0,Int2Fix(12),f_0);
  242.     SolidCylinder( 8,f_0p25,f_0p25,Int2Fix(12),f_8,false,hG,1,RA,&xFormInstance);
  243.  
  244.     /*    The light bulb itself
  245.      */
  246.     SetRenderingAttributes( &RA, 65535,65535,65535 );
  247.     SetInstanceReferenceFrame(f_0,f_0,f_0,f_2,f_2+f_0p5,f_2,f_0,Int2Fix(14),f_0);
  248.     SolidSphere(9,9,f_1,Int2Fix(9),false,hG,2,RA,&xFormInstance);
  249.  
  250.     /*    And the lamp's shade
  251.      */
  252.     SetRenderingAttributes( &RA, 42000,42000,42000 );
  253.     RA.transparency = f_0p25;
  254.     RA.framed        = true;
  255.     SetInstanceReferenceFrame(f_0,f_0,f_0,f_1,f_1,f_1,f_0,Int2Fix(12),f_0);
  256.     SolidCylinder( 8,f_3,f_10,Int2Fix(12),f_8,false,hG,3,RA,&xFormInstance);
  257.  
  258.     /*    A table to set it on
  259.      */
  260.     hG = NewGroup( 1 );        /* allocate the group and patches    */
  261.     (**hC).hG[1] = hG;        /* put group handle in collection    */    
  262.     GenRotatedSurfaceTable(hG,0);
  263.  
  264.     return hC;
  265. }
  266.  
  267. void    GenRotatedSurfaceBody(hGroup hG,short ixP)
  268. {
  269.     int            nDataPts = 8;
  270.     Point3d        DataPt[] =
  271.     {
  272.         {f_1,f_0,f_0}
  273.     ,    {f_2,f_1,f_0}
  274.     ,    {f_3,f_3,f_0}
  275.     ,    {f_2,f_4,f_0}
  276.     ,    {f_2,f_5,f_0}
  277.     ,    {f_1,f_6,f_0}
  278.     ,    {f_0,f_4,f_0}
  279.     ,    {f_0,f_2,f_0}
  280.     };
  281.     Point3d        axis = {f_0,f_1,f_0};    /* rotation axis */
  282.     RendAttr    RA;                        /* rendering attributes    */
  283.     
  284.     int        nPts;
  285.     Point3d    *pPts;
  286.     
  287.     HermiteCurve3d(HERMITE_CLOSEDCURVE,3,nDataPts,DataPt,&nPts,&pPts);
  288.     SetInstanceReferenceFrame(f_0,f_0,f_0,f_2,f_3,f_2,f_0,-Int2Fix(9),f_0);
  289.     SetRenderingAttributes( &RA, 32767,32767,42000 );
  290.     RotateToSurface
  291.         (    f_0, f_360, axis, 12,
  292.             nPts, pPts,
  293.             hG,ixP,RA, &xFormInstance
  294.         );
  295.     DisposPtr( (Ptr)pPts );
  296. }
  297.  
  298. void    GenRotatedSurfaceTable(hGroup hG,short ixP)
  299. {
  300.     int            nDataPts = 5;
  301.     Point3d        DataPt[] =
  302.     {
  303.         {f_0  ,-f_0p6,f_0}
  304.     ,    {f_3p6,-f_0p6,f_0}
  305.     ,    {f_3p6,-f_0p4,f_0}
  306.     ,    {f_3  , f_0  ,f_0}
  307.     ,    {f_0  , f_0  ,f_0}
  308.     };
  309.     Point3d        axis = {f_0,f_1,f_0};    /* rotation axis */
  310.     RendAttr    RA;                        /* rendering attributes    */
  311.     
  312.     SetInstanceReferenceFrame(f_0,f_0,f_0,f_6,f_2,f_6,f_0,-Int2Fix(9),f_0);
  313. #undef    _WOOD_
  314. #ifdef    _WOOD_
  315.     SetRenderingAttributes( &RA, 58000,36000,18000 );
  316.     RA.framed            =    true;
  317.     RA.frameColor.red    =    65000;
  318.     RA.frameColor.green    =    57000;
  319.     RA.frameColor.blue    =    18000;
  320.     RA.normalVisibility    =    true;
  321.     RA.texture = TX_WOOD;
  322.     SetPt3d( &RA.tx[TXI_WOOD].txRotations, Int2Fix(85),Int2Fix(30),f_0 );
  323.     SetPt3d( &RA.tx[TXI_WOOD].txScalars, f_2+f_0p5,f_2+f_0p5,f_2+f_0p5 );
  324.     SetPt3d( &RA.tx[TXI_WOOD].txTranslations, f_0,f_0,f_0 );
  325.     RA.tx[TXI_WOOD].txArgument[0] = 0;        /* do not add noise values        */
  326.     RA.tx[TXI_WOOD].txArgument[1] = f_0p6;    /* lightest grain                */
  327.     RA.tx[TXI_WOOD].txArgument[2] = f_0p5;    /* darkest grain                */
  328.     RA.tx[TXI_WOOD].txArgument[3] = 0;        /* not used for wood texture    */
  329. #else // _ROCK_
  330.     SetRenderingAttributes( &RA, 65000,65000,65000 );
  331.     RA.framed            =    true;
  332.     RA.frameColor.red    =    65000;
  333.     RA.frameColor.green    =    47000;
  334.     RA.frameColor.blue    =     3000;
  335.     RA.normalVisibility    =    true;
  336.     RA.texture = TX_ROCK;
  337.     SetPt3d( &RA.tx[TXI_ROCK].txRotations, Int2Fix(30),Int2Fix(0),Int2Fix(20) );
  338.     SetPt3d( &RA.tx[TXI_ROCK].txScalars, f_1,f_1,f_1 );
  339.     SetPt3d( &RA.tx[TXI_ROCK].txTranslations, f_45,f_0,f_0 );
  340.     RA.tx[TXI_ROCK].txArgument[0] = fixratio(16,1);
  341.     RA.tx[TXI_ROCK].txArgument[1] = fixratio(4,10);    
  342.     RA.tx[TXI_ROCK].txArgument[2] = fixratio(8,10);    
  343.     RA.tx[TXI_ROCK].txArgument[3] = fixratio(7,10);        
  344.     RA.diffusion        =     fixratio(15,100);
  345.     RA.specIndex        =     30;
  346.     RA.specularity        =    fixratio(85,100);
  347.     RA.ambience            =    fixratio(1,100);
  348. #endif    _WOOD_
  349.     RotateToSurface
  350.         (    f_0, f_360, axis, 8,
  351.             nDataPts, DataPt,
  352.             hG,ixP,RA, &xFormInstance
  353.         );
  354. }
  355.  
  356. void    SetRenderingAttributes(pRendAttr pRA,colorFactor r,colorFactor g,colorFactor b)
  357. {
  358.     pRA->R                    =    r;
  359.     pRA->G                    =    g;
  360.     pRA->B                    =    b;
  361.     pRA->frameColor.red        =    32767;
  362.     pRA->frameColor.green    =    32767;
  363.     pRA->frameColor.blue    =    32767;
  364.     pRA->lightSource        =    false;
  365.     pRA->distanceEffect        =    true;
  366.     pRA->ambientEffect        =    true;
  367.     pRA->normalVisibility    =    false;
  368.     pRA->framed                =    false;
  369.     pRA->patterned            =    true;
  370.     pRA->grayScaled            =    false;
  371.     pRA->texture            =    TX_NONE;
  372.     pRA->diffusion            =     f_0p5;
  373.     pRA->specIndex            =     20;
  374.     pRA->specularity        =    f_0p25;
  375.     pRA->ambience            =    f_0p1;
  376.     pRA->absorption            =    0;
  377.     pRA->translucence        =    0;
  378.     pRA->refraction            =    0;
  379.     pRA->transparency        =    0;
  380. }
  381.  
  382. pLighting    SetupLighting()
  383. {
  384.     pLighting    pL;
  385.     LtSource    LS[3];
  386.  
  387.     /*    create light sources
  388.      */
  389.     Set3dLtSource
  390.             (    &LS[0],65535,65535,65535,f_0p1,
  391.                 Int2Fix(  0 ), Int2Fix( 14 ), Int2Fix( 0 )
  392.             );
  393.  
  394.     Set3dLtSource
  395.             (    &LS[1],32767, 32767, 32767,f_1+f_0p5,
  396.                 Int2Fix( 180 ), Int2Fix( 180 ), Int2Fix( -80 )
  397.             );
  398.  
  399.     Set3dLtSource
  400.             (    &LS[2],32767, 65535, 65535,fixratio(29,10),
  401.                 Int2Fix( -200 ), Int2Fix(  180 ), Int2Fix(  200 )
  402.             );
  403.  
  404.     /*    set ambient light and store point sources
  405.      */
  406.     pL = NewLighting(32767, 32767, 32767,fixratio(5,100), 3, LS );
  407.     
  408.     /*    transform its coordinates into the viewer's (camera's) reference frame
  409.      */
  410.     TransformLighting(pL,&xFormViewer);
  411.  
  412.     /*    apply the ambient light color to the background (if we have color)
  413.      */
  414.     if( ColorPresent )
  415.         RGBBackColor( &pL->color );
  416.     return    pL;
  417. }
  418.